/* R. J. Cano, Aug 27 2016

Given N=[[2,-1],[2,1],[1,-2],[1,2],[-1,-2],[-1,2],[-2,-1],[-2,1]];
Let be L4=List([[7,2,0,1,0,5,7,3],[1,3,6,7,6,2,7,1],[0,5,7,4,6,5,1,0],[1,5,0,2,1,3,6,5],[1,2,6,7,6,5,1,7],[1,5,0,1,0,4,7,2],[0,4,7,5,6,2,7,1],[7,2,0,3,1,2,6,4]]);
Certain seq. a permutation of [1..8] relative to L4, which subsequently is relative to N, is a solution for 8*8 when r1=[1,1]; ...Indeed! it can be interpreted also as a magic square...

But the remaining code was all a messy waste of coffee, hehehe!

*/

#

my(L4:list,tester,tr,Sol:list,backup_M:list,backup_r:list,M,N,r);
/* * /
L4=List([[7,2,0,1,0,5,7,3],[1,3,6,7,6,2,7,1],[0,5,7,4,6,5,1,0],[1,5,0,2,1,3,6,5],[1,2,6,7,6,5,1,7],[1,5,0,1,0,4,7,2],[0,4,7,5,6,2,7,1],[7,2,0,3,1,2,6,4]]);
/ * */
L4=List();
N=[[2,-1],[2,1],[1,-2],[1,2],[-1,-2],[-1,2],[-2,-1],[-2,1]];
tester=matrix(33,33,i,j,0);

selfCrossing(x)={
  tester[17,17]=1;
  tr=[17,17];
  for(j=1,#x,
    tr+=N[x[j]+1];
    if(tester[tr[1],tr[2]],
      tr=[17,17];
      for(jj=1,j,
        tr+=N[x[jj]+1];
        tester[tr[1],tr[2]]*=0;
      );
      return(1);
      ,
       tester[tr[1],tr[2]]++
    )
  );
  return(0)
}

generate_L4()={
  my(u,a);
  forvec(y=vector(8,i,[0,7]),
    u=1;
    for(j=1,7,
      if((y[j]+y[j+1]==7)||(y[j]==y[j+1]),
        u*=0;j=8
      )
    );
    if(u,
      a=#vecsort(y,,8);
      if((4<a)&&(a<8),
        if(!selfCrossing(y),
          listput(L4,y)
        )
      )
    );
  ,0)
}

isSolution(M0,r0,w,k)={
  my(r=r0);
  for(j=1,8-k,
    r+=N[w[j]+1];
    if(!(((1<=r[1])&&(r[1]<=#M0[,1]))&&((1<=r[2])&&(r[2]<=#M0[1,]))),return(0));
    if(M0[r[1],r[2]],return(0),M0[r[1],r[2]]++)
  );
  listput(backup_M,M);
  M=M0;
  listput(backup_r,r1);
  r1=r;
  return(1)
}

Try(p=1,k,verbose=1)={
  my(q=0,i);
  for(j=1,p,
  i=1+q;
  while((i<=#L4)&&!isSolution(M,r1,L4[i],(j==p)*k),i++);
  if(i<=#L4,
    listput(Sol,i);
    q=0;
  ,
    if(#Sol>0,
      q=Sol[#Sol];
      listpop(Sol,#Sol);
      j--;
      M=backup_M[#backup_M];
      listpop(backup_M,#backup_M);
      r1=backup_r[#backup_r];
      listpop(backup_r,#backup_r)
      ,
      q=0
     );
   )
  );
  if(verbose,if(#Sol,print(":-) Something was found!\n\tSpecifically: ",Sol,"\n\nEnter \"describeSol()\" for details..."),print(" :-( Nothing was found.\n\t...Sorry.")));
}

resetBoardTo(a,b,c,d,verbose=1)={
  M=matrix(a,b,i,j,0);
  r1=[c,d]; /* r=[y,x]; */
  M[r1[1],r1[2]]=1;
  Sol=List();
  backup_M=List();
  backup_r=List();
  if(verbose,print("Current board (\"NEW\"): Size=",a,"*",b,"; Initial position [y,x]=[",c,",",d,"];"));
}

describeSol()={
  if(#Sol,
    for(j=1,#Sol,
      for(i=1,8,
        print1(L4[Sol[j]+1][i])
      );
      if(j==#Sol,print("..."),print1(","))
    )
  )
}

print("Loading/Generating database L4; Please wait...")
/* */ generate_L4(); /* */
print("\nReady!");